<template>
    <el-form label-width="100px" :model="spuInfo" :rules="spuRules" ref="spuFormRef">
        <el-form-item label="SPU名称" prop="spuName">
            <el-input placeholder="SPU名称" v-model="spuInfo.spuName"></el-input>
        </el-form-item>
        <el-form-item label="品牌" prop="tmId">
            <el-select placeholder="请选择品牌" v-model="spuInfo.tmId">
                <el-option v-for="trademark in trademarkList" :label="trademark.tmName" :value="trademark.tmName"
                    :key="trademark.id" />
            </el-select>
        </el-form-item>
        <el-form-item label="SPU描述" prop="description">
            <el-input type="textarea" :rows="3" v-model="spuInfo.description"></el-input>
        </el-form-item>
        <el-form-item label="SPU图片" prop="spuImageList">
            <el-upload v-model:file-list="spuInfo.spuImageList" :action="`${BASE_URL}/admin/product/upload`"
                list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
                :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
                <el-icon>
                    <Plus />
                </el-icon>
            </el-upload>

            <el-dialog v-model="dialogVisible">
                <img w-full :src="dialogImageUrl" alt="Preview Image" />
            </el-dialog>
        </el-form-item>
        <el-form-item label="销售属性" prop="spuSaleAttrList">
            <el-select v-model="spuInfo.spuSaleAttr" :placeholder="`还剩下${filterBaseSaleAttrList.length}个未选择`">
                <el-option v-for="baseSaleAttr in filterBaseSaleAttrList" :label="baseSaleAttr.name"
                    :value="baseSaleAttr.name" :key="baseSaleAttr.id" />
            </el-select>
            <el-button type="primary" :disabled="!spuInfo.spuSaleAttr" @click="addSpuSaleAttr">添加销售属性</el-button>
        </el-form-item>
        <el-form-item>
            <el-table border :data="spuInfo.spuSaleAttrList">
                <el-table-column label="序号" width="80px" type="index" align="center"></el-table-column>
                <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
                <el-table-column label="属性值名称列表">
                    <template v-slot="{ row }">
                        <el-tag v-for="tag in row.spuSaleAttrValueList" :key="tag" class="mx-1" closable
                            :disable-transitions="false" @click="handleClose(row, tag)">
                            {{ tag.saleAttrValueName }}
                        </el-tag>
                        <el-input v-if="row.inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20"
                            style="width:100px" size="small" @keyup.enter="handleInputConfirm(row)"
                            @blur="handleInputConfirm(row)" />
                        <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput(row)">
                            + New
                        </el-button>
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template v-slot="{ row, $index }">
                        <el-popconfirm confirm-button-text="确定" cancel-button-text="取消" :icon="InfoFilled"
                            icon-color="#626AEF" title="真的确定要删除此条数据么?" @confirm="deleteAttr(row.id)">
                            <template #reference>
                                <el-button title="删除" type="danger" size="small" :icon="Delete" />
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="spuSubmitForm(spuFormRef)">保存</el-button>
            <el-button @click="emits('changeScene', 1)">取消</el-button>
        </el-form-item>
    </el-form>
</template>

<script lang="ts">
export default {
    name: 'SpuForm'
}
</script>
<script lang="ts" setup>
import { ref, onMounted, reactive, computed, nextTick } from 'vue'
import { Plus, Edit, InfoFilled, Delete } from '@element-plus/icons-vue'
import { ElMessage, ElInput, type UploadFiles } from 'element-plus'
import type { UploadProps, UploadFile, FormInstance, FormRules } from 'element-plus'
import { reqGetBaseSaleAttrList, reqGetTrademarkList, reqSaveSpuInfo, reqUpdateSpuInfo, reqGetSpuImageList, reqGetSpuSaleAttrList } from '@/api/product/spu'
import { useCategoryListStore } from '@/stores/categoryList'
const categoryStore = useCategoryListStore()
const emits = defineEmits(['changeScene', 'getSpuInfo']) // 接收自定义事件
const props = defineProps(['currentSpuInfo'])

//添加或者删除基础销售属性值想换的变量
const inputValue = ref('')
const InputRef = ref<InstanceType<typeof ElInput>>()

//动态读取环境变量中的值
const BASE_URL = import.meta.env.VITE_API_URL


const dialogImageUrl = ref('')
const dialogVisible = ref(false)

//准备两个列表数组，trademarkList 品牌数组  baseSaleAttrList基本属性列表
const trademarkList = ref<any>([])
const baseSaleAttrList = ref<any>([])

const spuFormRef = ref<FormInstance>()


//定义一个储存spu相关的变量
const spuInfo = reactive({
    spuName: '',
    tmId: '',//spu品牌
    description: '',//spu描述
    spuSaleAttr: '',//收集选中的基本销售属性
    category3Id: '',//三级Id
    ...props.currentSpuInfo,
    spuImageList: [],//储存spu图片的数组
    spuSaleAttrList: [],//基本销售属性
})


// 添加校验规则
const spuRules = reactive<FormRules>({
    spuName: [
        { required: true, message: '请输入SPU名称', trigger: 'blur' },
        { min: 1, max: 10, message: 'SPU名称在1-10个字符之间', trigger: 'blur' }
    ],
    tmId: [{ required: true, message: '请选择SPU品牌', trigger: 'change' }],
    description: [{ required: true, message: '请输入SPU描述', trigger: 'blur' }],
    spuImageList: [{ required: true, message: '请选择一张图片', type: 'array', trigger: 'change' }],
    spuSaleAttrList: [{ required: true, message: '请至少添加一个属性', type: 'array', trigger: 'click' }]
})

// 1. 组件一挂载完毕，就要去发送请求 获取品牌列表和销售属性的值
onMounted(async () => {
    try {
        let promises = [reqGetTrademarkList(), reqGetBaseSaleAttrList()]
        const id = spuInfo.id
        if (id) {
            // 如果有id，此时说明是编辑操作
            promises = promises.concat([reqGetSpuImageList(id), reqGetSpuSaleAttrList(id)])
        }
        const [responseTrademarkList, responseBaseSaleAttrList, responseSpuImageList, responseSpuSaleAttrList] = await Promise.all(promises)
        trademarkList.value = responseTrademarkList
        baseSaleAttrList.value = responseBaseSaleAttrList
        if (responseSpuImageList && responseSpuSaleAttrList) {
            console.log(responseSpuImageList);

            spuInfo.spuImageList = responseSpuImageList.map(item => {
                return {
                    ...item,
                    name: item.imgName,
                    url: item.imgUrl
                }
            })
            spuInfo.spuSaleAttrList = responseSpuSaleAttrList
        }
    } catch (error) {
        ElMessage.error('获取品牌或属性失败...')
    }
})

// 2. 删除图片时执行的事件处理程序
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
    spuInfo.spuImageList = uploadFiles
}

// 3. 图片预览时要执行的事件处理程序
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
    dialogImageUrl.value = uploadFile.url!
    dialogVisible.value = true
}
// 4. 上传成功后的操作
const handleAvatarSuccess: UploadProps['onSuccess'] = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
    spuInfo.spuImageList = uploadFiles
    // 清空校验规则
    spuFormRef.value!.clearValidate(['spuImageList'])
}

// 5. 图片上传之前校验时要执行的事件处理程序
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
    const imgTypes = ['image/jpeg', 'image/jpg', 'image/png']
    if (!imgTypes.includes(rawFile.type)) {
        ElMessage.error('上传的图片格式必须是JPG/JPEG/PNG格式,请重试')
        return false
    } else if (rawFile.size / 1024 / 1024 > 2) {
        ElMessage.error('图片最大不能超过2M,请重试!')
        return false
    }
    return true
}

// 6. 添加销售属性值
const addSpuSaleAttr = () => {
    //6.1 添加属性之间要做个判断 如果有某个属性没有属性值的话，是不能添加下一个属性的
    const spuSaleAttrList = spuInfo.spuSaleAttrList
    if (spuSaleAttrList.length && spuSaleAttrList.some(item => item.spuSaleAttrValueList.length == 0)) {
        ElMessage.error('有属性值为空，请添加...')
        return // 不要添加了
    }

    const id = baseSaleAttrList.value.find(item => {
        return item.name == spuInfo.spuSaleAttr
    }).id
    // 6.2 添加新的属性
    spuInfo.spuSaleAttrList.push({
        baseSaleAttrId: id,
        inputVisible: false, //给当前行对象添加一个属性，用于控制按钮和输入框的显示
        saleAttrName: spuInfo.spuSaleAttr,//属性名 颜色 版本 尺寸
        spuSaleAttrValueList: [] //当前属性名对应的那些详情的属性值
    })
    spuInfo.spuSaleAttr = '' // 清空下拉框选项

    // 清空输入框的值
    spuInfo.spuSaleAttr = ''

}

//7、使用计算属性 获取剩余的基础销售属性
const filterBaseSaleAttrList = computed(() => {
    return baseSaleAttrList.value.filter(baseSalue => {
        return !spuInfo.spuSaleAttrList.find(item => baseSalue.name === item.saleAttrName)
    })
})

//8、删除销售属性
const deleteAttr = (index: number) => {
    spuInfo.spuSaleAttrList.splice(index, 1)
}

//以下三个函数是与销售属性值想相关的函数
const handleClose = (row, tag) => {
    //查找tag所在数组中的索引
    let index = row.spuSaleAttrValueList.indexOf(tag)
    row.spuSaleAttrValueList.splice(index, 1)
}

const showInput = row => {
    row.inputVisible = true
    nextTick(() => {
        InputRef.value!.input!.focus()
    })
}

// 添加属性值失去焦点或是回车后执行的函数
const handleInputConfirm = row => {
    if (inputValue.value) {
        // 如果当前需要添加的属性值已经存在了，则不能再添加 需要提示
        const spuSaleAttrValueList = row.spuSaleAttrValueList
        if (spuSaleAttrValueList.length && spuSaleAttrValueList.find(item => item.saleAttrValueName === inputValue.value)) {
            ElMessage.error('属性值不能重复,请更换一个')
            // inputVisible.value = false
            row.inputVisible = false
            inputValue.value = ''
            return // 不要向下执行了 也就是不要再添加属性了
        }
        const id = baseSaleAttrList.value.find(item => item.name === row.saleAttrName).id
        // dynamicTags.value.push(inputValue.value)
        row.spuSaleAttrValueList.push({
            baseSaleAttrId: id,
            saleAttrName: row.saleAttrName, // 当前属性名称 比如 颜色 版本 尺寸
            saleAttrValueName: inputValue.value // 具体的属性值
        })
    }
    // inputVisible.value = false
    row.inputVisible = false
    inputValue.value = ''
}

// 9、保存SpuInfo 到服务器
const spuSubmitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate(async (valid, fields) => {
        console.log(valid);

        if (valid) {
            // 对于要添加的属性值，再做一个验证，如果属性名有，而属性值为空的话，也不能提交
            // 再判断一下，基础销售是不是有属性值，如果有一项无值 不能提交
            const spuSaleAttrList = spuInfo.spuSaleAttrList
            if (spuSaleAttrList.length && !spuSaleAttrList.every(item => item.spuSaleAttrValueList.length)) {
                ElMessage.error('有属性值为空，请重新添加...')
                return // 不要添加了
            }
            spuInfo.spuImageList = spuInfo.spuImageList.map(item => {
                return {
                    imgUrl: item.response?.data || item.url,
                    imgName: item.name
                }
            })
            spuInfo.category3Id = categoryStore.category3Id
            if (spuInfo.id) {
                // 此时是更新操作
                console.log(spuInfo)
                await reqUpdateSpuInfo(spuInfo)
            } else {
                // 才是真正的添加spuInfo
                await reqSaveSpuInfo(spuInfo)
            }

            ElMessage.success('操作Spu成功')
            // 跳转到列表页
            emits('changeScene', 1)
        } else {
            // console.log('error submit!', fields)
            ElMessage.error('提交失败...')
        }
    })
}
</script>

<style>
</style>